package com.learn.other.result;

import com.learn.other.enums.CodeEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author DJJ_F
 * @version 1.0
 * @date 2025/03/28
 * @description R对象是对响应结果的封装
 * 使用了泛型,建造模式
 */
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class R<T> {
    private int code;
    private String msg;
    private T data;

    /**
     * public 与 返回值中间<T>非常重要，可以理解为声明此方法为泛型方法。
     * 只有声明了<T>的方法才是泛型方法，泛型类中的使用了泛型的成员方法并不是泛型方法。
     * <T>表明该方法将使用泛型类型T，此时才可以在方法中使用泛型类型T。
     * 与泛型类的定义一样，此处T可以随便写为任意标识，常见的如T、E等形式的参数常用于表示泛型。
     * 泛型方法随着我们的传入参数类型不同，他得到的类型也不同。泛型方法能使方法独立于类而产生变化。
     * @param msg 需要传入的消息
     * @param data 需要返回的数据
     * @return R<T> 特定数据类型的结果
     */
    public static <T> R<T> OK(String msg, T data) {
        // <T>价值builder()前面
        return R.<T>builder()
                // 取的时候通过get方法取，而不是写死
                .code(CodeEnum.OK.getCode())
                .msg(CodeEnum.OK.getMsg())
                .data(data)
                .build();
    }

    /**
     * 构造模式支持只给需要的属性赋值
     * @param msg
     * @return R<T>
     */
    public static <T> R<T> OK(String msg) {
        return R.<T>builder()
                .code(200)
                .msg(msg)
                .build();
    }
    public static <T> R<T> OK(T data) {
        return R.<T>builder()
                .code(200)
                .msg("成功")
                .data(data)
                .build();
    }
    /**
     * 方法的重载，参数列表不同
     * @param code
     * @return R<T>
     */
    public static <T> R<T> FAIL(int code) {
        return FAIL(code, null);
    }
    public static <T> R<T> FAIL(int code, String msg) {
        return R.<T>builder()
                .code(code)
                .msg(msg)
                .build();
    }
}
